package Streaming;


import org.apache.commons.collections.MapUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: 蔡翔
 * @Date: 2019/10/5 19:28
 * @Version 1.0
 *
 * 收集器的详细用法（重要）
 */
class Student{
    private String name;
    private Integer age;
    private Integer grade;
    private Integer nianling;
    public Student(String name,Integer age,Integer grade,Integer nianling){
        this.name = name;
        this.age = age;
        this.grade = grade;
        this.nianling = nianling;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getGrade() {
        return grade;
    }

    public void setGrade(Integer grade) {
        this.grade = grade;
    }

    public Integer getNianling() {
        return nianling;
    }

    public void setNianling(Integer nianling) {
        this.nianling = nianling;
    }
}
public class CollectDemo {
    public static void main(String[] args) {
        List<Student> list = Arrays.asList(
                new Student("a1",65,33,1),
                new Student("a2",5,100,1),
                new Student("a3",16,33,1),
                new Student("a4",60,100,1),
                new Student("a5",33,63,1),
                new Student("a6",22,11,1),
                new Student("a7",11,63,0),
                new Student("a8",65,11,1),
                new Student("a9",20,33,0),
                new Student("a10",66,11,0)
        );

        //得到所有学生的年龄列表,,收集器是流的最终操作 ;;在已有的数据源上 是这样建流了。
        // map操作 s -> s.getAge() 返回的是s.getAge()，返回map后是一个 新的数据流。
        //s -> s.getAge() 最好使用方法引用 的形式；； Student::getAge
        List<Integer> ages = list.stream().map(s -> s.getAge())
                .collect(Collectors.toList());

        // 如果是Set 可以去重
        Set<Integer> agesa = list.stream().map(s -> s.getAge())
                .collect(Collectors.toSet());

        // 指定集合类型
        Set<Integer> agees = list.stream().map(s -> s.getAge())
                .collect(Collectors.toCollection(TreeSet::new));

        System.out.println("所有学生的年龄："+ages);
        System.out.println("所有学生的年龄："+agesa);


        //统计汇总信息 ,,summarizingXxx 是用于数据的汇总，，summarizingInt 是对数据的进行汇总。
        IntSummaryStatistics collect = list.stream().collect(Collectors.summarizingInt(Student::getAge));
        System.out.println("年龄汇总信息："+collect);
        //输出结果为： 年龄汇总信息：IntSummaryStatistics{count=10, sum=363, min=5, average=36.300000, max=66}

        //分块   ---  就是根据一定的规则吧数据分成2块
        //partitioningBy就是分块，依据student -> student.getNianling() 是否为0分块
        Map<Boolean, List<Student>> collect1 = list.stream().collect(Collectors
                .partitioningBy(student -> student.getNianling() == 0));
        //System.out.println("nianling == 0"+collect1);
        MapUtils.verbosePrint(System.out,"男女生列表",collect1);

        //分组（依据grade 班级分组）
        Map<Integer, List<Student>> collect2 = list.stream().collect(
                // 按照 Grade 来分组。有几个不同的grade，就分几组。
                Collectors.groupingBy(Student::getGrade)
        );
        MapUtils.verbosePrint(System.out,"学生班级列表",collect2);

        //依据班级分好的组，得到班级学生的个数（因为每个分组都是List也能构成数据流stream）
        //注意Map<Integer, Long> 和Function<Integer,Integer>的区别；Map<A,B> 其中AB是键值对的关系。
        Map<Integer, Long> collect3 = list.stream().collect(
                // 按照 Grade 来分组。有几个不同的grade，就分几组。
                Collectors.groupingBy(
                        Student::getGrade,
                        //groupingBy 的第二个参数就是对 分好组的，每组Stream流进行操作
                        Collectors.counting()
                )
        );
        MapUtils.verbosePrint(System.out,"班级学生个数列表",collect3);


    }
}